using System.Collections.Generic;
using Game.XH;
using UnityEngine;

namespace Game.Component
{
	public class DepthSystem
	{
		public BaseItem item;

		public Transform transform;

		public DepthSystem parentNode;

		public DepthSystem baseNode;

		public List<DepthSystem> aheadNodes = new List<DepthSystem>();

		public List<DepthSystem> behindNodes = new List<DepthSystem>();

		public List<DepthSystem> frontNodes = new List<DepthSystem>();

		public List<DepthSystem> backNodes = new List<DepthSystem>();

		public DepthType depthType = DepthType.Behind;

		public bool isForceFront;

		public int frontForceFrontAmount;

		public float depth;

		public float frontThickness;

		public float backThickness;

		public DepthSystem(BaseItem item)
		{
			this.item = item;
			transform = item.transform;
		}

		public DepthSystem(Transform trans)
		{
			item = null;
			transform = trans;
		}

		public void AddChildNode(DepthSystem node, DepthType depthType, bool isForceFront = false)
		{
			if (node.parentNode == this && node.depthType == depthType)
			{
				return;
			}
			if (node.parentNode != null)
			{
				node.parentNode.RemoveChildNode(node);
			}
			node.depthType = depthType;
			node.SetBaseNode(baseNode);
			node.parentNode = this;
			node.isForceFront = isForceFront;
			if (node.depthType == DepthType.Ahead)
			{
				aheadNodes.Add(node);
			}
			else if (node.depthType == DepthType.Behind)
			{
				behindNodes.Add(node);
			}
			else if (node.depthType == DepthType.Front)
			{
				if (!node.isForceFront && frontForceFrontAmount > 0)
				{
					int count = frontNodes.Count;
					int num = count;
					for (int i = 0; i < frontNodes.Count; i++)
					{
						if (frontNodes[i].isForceFront)
						{
							num = i;
							break;
						}
					}
					if (count != num)
					{
						frontNodes.Insert(num, node);
					}
					else
					{
						frontNodes.Add(node);
					}
				}
				else
				{
					frontNodes.Add(node);
				}
				if (isForceFront)
				{
					frontForceFrontAmount++;
				}
			}
			else if (node.depthType == DepthType.Back)
			{
				backNodes.Add(node);
			}
			AddThickness(node, node.GetThickness());
		}

		public void SetBaseNode(DepthSystem node)
		{
			baseNode = node;
			SetChildNode(frontNodes, node);
			SetChildNode(aheadNodes, node);
			SetChildNode(behindNodes, node);
			SetChildNode(backNodes, node);
		}

		private void SetChildNode(List<DepthSystem> list, DepthSystem node)
		{
			for (int i = 0; i < list.Count; i++)
			{
				list[i].SetBaseNode(node);
			}
		}

		public void AddThickness(DepthSystem node, float addVal)
		{
			if (node.depthType == DepthType.Ahead || node.depthType == DepthType.Front)
			{
				frontThickness += addVal;
			}
			else
			{
				backThickness += addVal;
			}
			if (parentNode != null)
			{
				parentNode.AddThickness(this, addVal);
			}
		}

		public void MinusThickness(DepthSystem node, float minusVal)
		{
			if (node.depthType == DepthType.Ahead || node.depthType == DepthType.Front)
			{
				frontThickness -= minusVal;
			}
			else
			{
				backThickness -= minusVal;
			}
			if (parentNode != null)
			{
				parentNode.MinusThickness(this, minusVal);
			}
		}

		public void RemoveChildNode(DepthSystem node)
		{
			if (node.depthType == DepthType.Ahead)
			{
				if (!aheadNodes.Remove(node))
				{
					return;
				}
			}
			else if (node.depthType == DepthType.Behind)
			{
				if (!behindNodes.Remove(node))
				{
					return;
				}
			}
			else if (node.depthType == DepthType.Front)
			{
				if (node.isForceFront)
				{
					frontForceFrontAmount--;
				}
				if (!frontNodes.Remove(node))
				{
					return;
				}
			}
			else if (node.depthType == DepthType.Back && !backNodes.Remove(node))
			{
				return;
			}
			MinusThickness(node, node.GetThickness());
		}

		public float GetThickness()
		{
			return frontThickness + backThickness + 0.001f;
		}

		public void SortBaseNode()
		{
			if (baseNode != null)
			{
				baseNode.SortSelf(true);
			}
		}

		public void SortSelf(bool needUpdatePosition)
		{
			depth = transform.position.z;
			Sort(needUpdatePosition, depth);
			if (!needUpdatePosition)
			{
				return;
			}
			if (item != null)
			{
				item.UpdateFrontDepth();
				item.UpdateBackDepth();
				return;
			}
			for (int i = 0; i < frontNodes.Count; i++)
			{
				UpdateInsideDepth(frontNodes[i]);
			}
			for (int j = 0; j < aheadNodes.Count; j++)
			{
				UpdateInsideDepth(aheadNodes[j]);
			}
			for (int k = 0; k < behindNodes.Count; k++)
			{
				UpdateInsideDepth(behindNodes[k]);
			}
			for (int l = 0; l < backNodes.Count; l++)
			{
				UpdateInsideDepth(backNodes[l]);
			}
		}

		private void UpdateInsideDepth(DepthSystem sys)
		{
			if (sys != null && sys.item != null)
			{
				sys.item.UpdateFrontDepth();
				sys.item.UpdateBackDepth();
			}
		}

		public void Sort(bool needUpdatePosition, float startDepth)
		{
			SortChild(aheadNodes);
			SortChild(behindNodes);
			float num = 0f;
			for (int i = 0; i < aheadNodes.Count; i++)
			{
				num -= aheadNodes[i].backThickness + 0.001f;
				aheadNodes[i].Sort(needUpdatePosition, num);
				num -= aheadNodes[i].frontThickness;
			}
			for (int j = 0; j < frontNodes.Count; j++)
			{
				num -= frontNodes[j].backThickness + 0.001f;
				frontNodes[j].Sort(needUpdatePosition, num);
				num -= frontNodes[j].frontThickness;
			}
			depth = startDepth;
			if (needUpdatePosition)
			{
				if (parentNode != null)
				{
					transform.position = new Vector3(transform.position.x, transform.position.y, parentNode.transform.position.z + depth);
				}
				else
				{
					transform.SetLocalZ(depth);
				}
			}
			num = 0f;
			for (int num2 = behindNodes.Count - 1; num2 >= 0; num2--)
			{
				num += behindNodes[num2].frontThickness + 0.001f;
				behindNodes[num2].Sort(needUpdatePosition, num);
				num += behindNodes[num2].backThickness;
			}
			for (int num3 = backNodes.Count - 1; num3 >= 0; num3--)
			{
				num += backNodes[num3].frontThickness + 0.001f;
				backNodes[num3].Sort(needUpdatePosition, num);
				num += backNodes[num3].backThickness;
			}
		}

		public void RemoveFromParent()
		{
			if (parentNode != null)
			{
				parentNode.RemoveChildNode(this);
			}
		}

		private void SortChild(List<DepthSystem> list)
		{
			for (int i = 0; i < list.Count - 1; i++)
			{
				for (int num = list.Count - 1; num > i; num--)
				{
					if (list[num - 1].item.archiveData.y < list[num].item.archiveData.y)
					{
						DepthSystem value = list[num];
						list[num] = list[num - 1];
						list[num - 1] = value;
					}
				}
			}
		}

		public void DebugNodeChild()
		{
		}
	}
}
